/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 * Global Trust Authority is licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

use serde::Serialize;
use crate::entities::{cert_info, cert_revoked_list};
use crate::entities::cert_resp_info::CertRespInfo;

#[derive(Serialize)]
pub struct QueryResponse {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub message: Option<String>,
    pub certs: Vec<CertRespInfo>,
}

impl QueryResponse {
    /// Converts a vector of certificate and revoked certificate models into a `QueryResponse`.
    ///
    /// This function maps the database models to the response structure, handling
    /// optional fields and converting binary content to strings.
    ///
    /// # Arguments
    /// * `certs` - A vector of tuples, where each tuple contains a `cert_info::Model`
    ///             and an optional `cert_revoked_list::Model`.
    ///
    /// # Returns
    /// A `QueryResponse` struct containing the formatted certificate information.
    pub fn from_models(
        certs: Vec<(cert_info::Model, Option<cert_revoked_list::Model>)>,
    ) -> Self {
        QueryResponse {
            message: None,
            certs: certs
                .into_iter()
                .map(|(cert_info, cert_revoked)| CertRespInfo {
                    cert_id: Some(cert_info.id),
                    cert_name: cert_info.name,
                    description: cert_info.description,
                    content: cert_info.cert_info.map(|u| String::from_utf8_lossy(&u).to_string()),
                    cert_type: if let Some(cert_type) = cert_info.cert_type {
                        Some(
                            cert_type.as_array().unwrap().iter().filter_map(|v| v.as_str().map(String::from)).collect(),
                        )
                    } else {
                        None
                    },
                    is_default: cert_info.is_default,
                    version: cert_info.version,
                    create_time: cert_info.create_time,
                    update_time: cert_info.update_time,
                    valid_code: cert_info.valid_code,
                    cert_revoked_date: cert_revoked.as_ref().and_then(|r| r.cert_revoked_date),
                    cert_revoked_reason: cert_revoked.as_ref().and_then(|r| r.cert_revoked_reason.clone()),
                })
                .collect(),
        }
    }
}

#[derive(Serialize)]
pub struct DeleteResponse {
    pub message: String,
}

#[derive(Default, Serialize)]
pub struct AddCertResponse {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub message: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cert: Option<CertRespInfo>,
}